package com.dx.mes.service.brm.service;

import static com.dx.mes.common.bean.def.GenericDef.ACTION_FLG_ADD;
import static com.dx.mes.common.bean.def.GenericDef.ACTION_FLG_DELETE;
import static com.dx.mes.common.bean.def.GenericDef.ACTION_FLG_QUERY;
import static com.dx.mes.common.bean.def.GenericDef.ACTION_FLG_UPDATE;
import static com.dx.mes.common.bean.def.GenericDef.ACTION_FLG_LIST_WHOLE;
import static com.dx.mes.common.bean.def.GenericDef.E_BIS_OPE;
import static com.dx.mes.common.bean.def.GenericDef.E_READ_NOT_FOUND;
import static com.dx.mes.common.bean.def.GenericDef.RETURN_CODE_OK;
import static com.dx.mes.common.bean.def.GenericDef.RETURN_CODE_SET_ERROR;
import static com.dx.mes.common.bean.def.GenericDef.RETURN_CODE_UNKNOWN;
import static com.dx.mes.common.bean.def.GenericDef.RETURN_MESG_OK;
import static com.dx.mes.common.bean.def.GenericDef.TRX_OUT;
import static com.dx.mes.common.bean.def.GenericDef.T_FBPBISOPE;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import com.dx.common.table.ppt.*;
import com.dx.mes.common.dao.IBisPathDao;
import com.dx.mes.common.dao.IBisPathiDao;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dx.mes.common.dao.IBisOpeDao;
import com.dx.mes.common.transcoder.util.AppContext;
import com.dx.mes.common.transcoder.util.JacksonUtil;
import com.dx.mes.common.transcoder.util.LogUtils;
import com.dx.mes.common.transcoder.util.Util;
import com.dx.mes.facade.brm.service.IFbpbisopeService;
import com.dx.mes.facade.brm.tx.Fbpbisope.FbpbisopeI;
import com.dx.mes.facade.brm.tx.Fbpbisope.FbpbisopeIA;
import com.dx.mes.facade.brm.tx.Fbpbisope.FbpbisopeO;
import com.dx.mes.facade.brm.tx.Fbpbisope.FbpbisopeOA;

@Service("fbpbisopeService")
@SuppressWarnings({"unchecked"})
public class FbpbisopeService implements IFbpbisopeService {
    private static final String TX_NAME = T_FBPBISOPE;
    private LogUtils logUtils;

    @Autowired
    private IBisOpeDao bisOpeDao;
    @Autowired
    private IBisPathDao bisPathDao;
    @Autowired
    private IBisPathiDao bisPathiDao;

    public String subMainProc(String evt_no, String strInMsg) {
        AppContext.clear();
        AppContext.setCurrServiceName(FbpbisopeService.class.getSimpleName());
        AppContext.setCurrEventNumber(evt_no);
        logUtils = new LogUtils(FbpbisopeService.class);
        logUtils.info("[InTrx:" + strInMsg + "]");

        Session session = bisOpeDao.getCrSession();
        String strOutTrx = null;
        FbpbisopeO outTrx = new FbpbisopeO();
        try {

            outTrx.setTrx_id(TX_NAME);
            outTrx.setType_id(TRX_OUT);
            outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));

            FbpbisopeI inTrx = JacksonUtil.fromJson(strInMsg, FbpbisopeI.class);
            char action_flg = inTrx.getAction_flg().charAt(0);
            switch (action_flg) {
                case ACTION_FLG_QUERY:
                    outTrx = queryByCondition(inTrx);
                    break;
                case ACTION_FLG_ADD:
                    addFnc(inTrx, outTrx);
                    break;
                case ACTION_FLG_UPDATE:
                    updateFnc(inTrx, outTrx);
                    break;
                case ACTION_FLG_DELETE:
                    outTrx = deleteFnc(inTrx);
                    break;
                case ACTION_FLG_LIST_WHOLE:
                    listAllFnc(inTrx, outTrx);
                    break;
                case 'P':
                    outTrx = queryByPath(inTrx);
                    break;
                default:
                    outTrx = errActionFnc();
            }
            if (RETURN_CODE_OK.equals(outTrx.getRtn_code())) {
                session.flush();
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        } catch (Exception ex) {
            logUtils.info("[" + Util.stackTraceToString(ex) + "]");
            outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
            outTrx.setRtn_mesg("程序执行异常");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } finally {
            strOutTrx = JacksonUtil.toJSONStr(outTrx);
            logUtils.info("[OutTrx:" + strOutTrx + "]");
        }
        return strOutTrx;
    }

    public FbpbisopeO queryByCondition(FbpbisopeI inTrx) {
        FbpbisopeO outTrx = new FbpbisopeO();
        outTrx.setTrx_id(TX_NAME);
        outTrx.setType_id(TRX_OUT);

        FbpbisopeIA iary = inTrx.getIary().get(0);
        /***
         * 支持 按ope_id,ope_ver 模糊查询
         ***/
        String ope_id = iary.getOpe_id();
        String ope_ver = iary.getOpe_ver();
        String tool_run_mode = iary.getTool_run_mode();
        String hql = "FROM Bis_ope where 1=1";
        if (ope_id != null) {
            if (ope_id.indexOf('*') == -1) {
                hql = hql + " and ope_id='" + ope_id + "'";
            } else {
                hql = hql + " and ope_id like '" + ope_id.replace('*', '%') + "'";
            }
        }
        if (ope_ver != null) {
            if (ope_ver.indexOf('*') == -1) {
                hql = hql + " and ope_ver='" + ope_ver + "'";
            } else {
                hql = hql + " and ope_ver like '" + ope_ver.replace('*', '%') + "'";
            }
        }
        if (tool_run_mode != null) {
            hql = hql + " and tool_run_mode = '" + tool_run_mode + "'";
        }
        List<Bis_ope> bisOpeList = bisOpeDao.find(hql);
        List<FbpbisopeOA> oaryList = new ArrayList<FbpbisopeOA>();
        for (Bis_ope bis_ope : bisOpeList) {
            FbpbisopeOA oary = new FbpbisopeOA();
            oary.setOpe_id(bis_ope.getId().getOpe_id());
            oary.setOpe_ver(bis_ope.getId().getOpe_ver());
            oary.setOpe_dsc(bis_ope.getOpe_dsc());
            oary.setProc_id(bis_ope.getProc_id());
            oary.setUp_load_id(bis_ope.getUp_load_id());
            oary.setDn_load_id(bis_ope.getDn_load_id());
            oary.setDept_id(bis_ope.getDept_id());
            oary.setToolg_id(bis_ope.getToolg_id_fk());
            oary.setTool_run_mode(bis_ope.getTool_run_mode());
            oaryList.add(oary);
        }
        outTrx.setOary(oaryList);
        outTrx.setTbl_cnt(oaryList.size());
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return outTrx;
    }

    public FbpbisopeO deleteFnc(FbpbisopeI inTrx) {
        FbpbisopeO outTrx = new FbpbisopeO();
        outTrx.setTrx_id(TX_NAME);
        outTrx.setType_id(TRX_OUT);

        FbpbisopeIA iary = inTrx.getIary().get(0);
        String ope_id = iary.getOpe_id();
        String ope_ver = iary.getOpe_ver();
        Bis_opeId id = new Bis_opeId();
        id.setOpe_id(ope_id);
        id.setOpe_ver(ope_ver);
        Bis_ope bisOpe = bisOpeDao.getWithLock(id, LockMode.UPGRADE);
        if (bisOpe == null) {
            outTrx.setRtn_code(E_BIS_OPE + E_READ_NOT_FOUND + "");
            outTrx.setRtn_code("not found ope");
            return outTrx;
        }
        bisOpeDao.delete(bisOpe);
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return outTrx;
    }

    public FbpbisopeO errActionFnc() {
        FbpbisopeO outTrx = new FbpbisopeO();
        outTrx.setTrx_id(TX_NAME);
        outTrx.setType_id(TRX_OUT);
        outTrx.setRtn_code("0000009");
        outTrx.setRtn_mesg("Invalid Action_flg");
        return outTrx;
    }

    public void addFnc(FbpbisopeI inTrx, FbpbisopeO outTrx) {
        FbpbisopeIA iary = inTrx.getIary().get(0);
        StringBuffer rsvInfoBuffer = new StringBuffer();
        Timestamp current_timestamp = Util.getCurrentTimestamp();
        // check exit
        Bis_opeId opeId = new Bis_opeId();
        opeId.setOpe_id(iary.getOpe_id());
        opeId.setOpe_ver(iary.getOpe_ver());
        Bis_ope bisope = bisOpeDao.get(opeId);

        if (bisope != null) {
            outTrx.setRtn_code("301234");
            outTrx.setRtn_mesg("代码为[" + iary.getOpe_id() + "]，版本为[" + iary.getOpe_ver() + "]的站点已经存在!请确认！");
            return;
        }
        //
        Bis_ope bis_ope = new Bis_ope();

        bis_ope.setId(opeId);
        bis_ope.setOpe_dsc(iary.getOpe_dsc());
        bis_ope.setProc_id(iary.getProc_id());
        bis_ope.setTool_run_mode(iary.getTool_run_mode());
        bis_ope.setDept_id(iary.getDept_id());
        bis_ope.setToolg_id_fk(iary.getToolg_id());
        bis_ope.setUp_load_id(iary.getUp_load_id());
        bis_ope.setDn_load_id(iary.getDn_load_id());
        bis_ope.setEvt_usr(inTrx.getEvt_usr());
        bis_ope.setEvt_timestamp(Util.getCurrentTimestamp());
        bisOpeDao.save(bis_ope);

        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
    }

    public void updateFnc(FbpbisopeI inTrx, FbpbisopeO outTrx) {
        FbpbisopeIA iary = inTrx.getIary().get(0);
        Timestamp current_timestamp = Util.getCurrentTimestamp();
        Bis_opeId opeId = new Bis_opeId();
        opeId.setOpe_id(iary.getOpe_id());
        opeId.setOpe_ver(iary.getOpe_ver());
        Bis_ope bisOpe = bisOpeDao.get(opeId);
        if (bisOpe == null) {
            outTrx.setRtn_code(E_READ_NOT_FOUND + "");
            outTrx.setRtn_mesg("not Found Record[BIS_OPE]");
            return;
        }

        if (iary.getOpe_dsc() != null) {
            bisOpe.setOpe_dsc(iary.getOpe_dsc());
        }
        if (iary.getProc_id() != null) {
            bisOpe.setProc_id(iary.getProc_id());
        }
        if (iary.getTool_run_mode() != null) {
            bisOpe.setTool_run_mode(iary.getTool_run_mode());
            ;
        }
        if (iary.getDept_id() != null) {
            bisOpe.setDept_id(iary.getDept_id());
        }
        if (iary.getToolg_id() != null) {
            bisOpe.setToolg_id_fk(iary.getToolg_id());
        }
        if (iary.getUp_load_id() != null) {
            bisOpe.setUp_load_id(iary.getUp_load_id());
        }
        if (iary.getDn_load_id() != null) {
            bisOpe.setDn_load_id(iary.getDn_load_id());
        }

        bisOpe.setEvt_usr(inTrx.getEvt_usr());
        bisOpe.setEvt_timestamp(current_timestamp);
        bisOpeDao.update(bisOpe);

        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
    }

    public void listAllFnc(FbpbisopeI inTrx, FbpbisopeO outTrx) {
        List<FbpbisopeOA> oaryList = new ArrayList<FbpbisopeOA>();
        String hql = "FROM Bis_ope where 1=1";
        List<Bis_ope> bisOpeList = bisOpeDao.find(hql);
        for (Bis_ope bis_ope : bisOpeList) {
            FbpbisopeOA oary = new FbpbisopeOA();
            oary.setOpe_id(bis_ope.getId().getOpe_id());
            oary.setOpe_ver(bis_ope.getId().getOpe_ver());
            oary.setOpe_dsc(bis_ope.getOpe_dsc());
            oary.setProc_id(bis_ope.getProc_id());
            oary.setToolg_id(bis_ope.getToolg_id_fk());
            oary.setTool_run_mode(bis_ope.getTool_run_mode());
            oaryList.add(oary);
        }
        outTrx.setOary(oaryList);
        outTrx.setTbl_cnt(oaryList.size());
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
    }

    public FbpbisopeO queryByPath(FbpbisopeI inTrx) {
        FbpbisopeO outTrx = new FbpbisopeO();
        outTrx.setTrx_id(TX_NAME);
        outTrx.setType_id(TRX_OUT);

        FbpbisopeIA iary = inTrx.getIary().get(0);
        /***
         * 支持 按ope_id,ope_ver 模糊查询
         ***/
        String pathId = iary.getPath_id();
        String pathVer = iary.getPath_ver();
        Bis_pathiId bis_pathiId = new Bis_pathiId();
        bis_pathiId.setPath_id(pathId);
        bis_pathiId.setPath_ver(pathVer);
        Bis_pathi bis_pathi = bisPathiDao.get(bis_pathiId);
        if(null == bis_pathi){
            outTrx.setRtn_code("301234");
            outTrx.setRtn_mesg("工艺路线不存在");
            return outTrx;
        }
        String hql = "FROM Bis_path where 1=1 and path_id_fk='" + pathId + "' and path_ver_fk='" + pathVer + "'";
        List<Bis_path> bisPathList = bisPathDao.find(hql);
        List<FbpbisopeOA> oaryList = new ArrayList<FbpbisopeOA>();
        for (Bis_path bis_path : bisPathList) {
            FbpbisopeOA oary = new FbpbisopeOA();
            oary.setOpe_no(bis_path.getId().getCr_ope_no());
            oary.setOpe_id(bis_path.getCr_ope_id_fk());
            oary.setOpe_ver(bis_path.getCr_ope_ver_fk());
            Bis_opeId bis_opeId = new Bis_opeId();
            bis_opeId.setOpe_id(bis_path.getCr_ope_id_fk());
            bis_opeId.setOpe_ver(bis_path.getCr_ope_ver_fk());
            Bis_ope bis_ope = bisOpeDao.get(bis_opeId);
            oary.setOpe_dsc(bis_ope.getOpe_dsc());
            oaryList.add(oary);
        }
        outTrx.setOary(oaryList);
        outTrx.setTbl_cnt(oaryList.size());
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return outTrx;
    }
}
